using AutoMapper;
using B.S.Medical.Api.Write.Application.Command.Doctor;
using B.S.Medical.Domain.Doctor;
using B.S.Medical.ErrorCode;
using B.S.Medical.Infrastructure;
using B.S.Medical.Infrastructure.Interface;
using MediatR;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;

namespace B.S.Medical.Api.Write.Application.Handler.Doctor
{
    /// <summary>
    /// 医生修改处理器
    /// </summary>
    public class UpdateDoctorHandler : IRequestHandler<UpdateDoctorCommand, ApiResult<int>>
    {
        private readonly IBaseRepository<DoctorModel> _doctorRepository;
        private readonly IBaseRepository<DoctorLabelModel> _doctorLabelRepository;
        private readonly IMapper _mapper;
        private readonly ILogger<UpdateDoctorHandler> _logger;
        private readonly MyDbContext _dbContext;

        public UpdateDoctorHandler(IBaseRepository<DoctorModel> doctorRepository,
                                  IBaseRepository<DoctorLabelModel> doctorLabelRepository,
                                  IMapper mapper,
                                  ILogger<UpdateDoctorHandler> logger,
                                  MyDbContext dbContext)
        {
            _doctorRepository = doctorRepository;
            _doctorLabelRepository = doctorLabelRepository;
            _mapper = mapper;
            _logger = logger;
            _dbContext = dbContext;
        }

        public async Task<ApiResult<int>> Handle(UpdateDoctorCommand request, CancellationToken cancellationToken)
        {
            ApiResult<int> res = new ApiResult<int>();
            try
            {
                using (var transaction = await _dbContext.Database.BeginTransactionAsync(cancellationToken))
                {
                    try
                    {
                        var doctor = _doctorRepository.GetAll().FirstOrDefault(d => d.Id == request.DoctorId && !d.IsDeleted);
                        if (doctor == null)
                        {
                            res.Msg = "未找到该医生!";
                            res.Code = ApiEnum.Fail;
                            _logger.LogError($"未找到医生，ID:{request.DoctorId}");
                            return res;
                        }
                        // 更新基本信息
                        doctor.DoctorName = request.DoctorName;
                        doctor.Photo = request.Photo;
                        doctor.CampusId = request.CampusId;
                        doctor.DepartmentId = request.DepartmentId;
                        doctor.JobTitleId = request.JobTitleId;
                        doctor.Copayfee = request.Copayfee;
                        doctor.Consultationfee = request.Consultationfee;
                        doctor.Briefly = request.Briefly;
                        doctor.Status = request.Status;

                        var r = await _doctorRepository.UpdateAsync(doctor);
                        if (r > 0)
                        {
                            // 处理标签
                            var oldLabels = _dbContext.DoctorLabelModel.Where(l => l.DoctorId == doctor.Id).ToList();
                            _dbContext.DoctorLabelModel.RemoveRange(oldLabels);
                            if (request.LaberIds != null && request.LaberIds.Count > 0)
                            {
                                List<DoctorLabelModel> doctorLabels = new List<DoctorLabelModel>();
                                foreach (var laberId in request.LaberIds)
                                {
                                    doctorLabels.Add(new DoctorLabelModel
                                    {
                                        DoctorId = doctor.Id,
                                        LaberId = laberId,
                                        IsDeleted = false
                                    });
                                }
                                await _dbContext.DoctorLabelModel.AddRangeAsync(doctorLabels, cancellationToken);
                            }
                            await _dbContext.SaveChangesAsync(cancellationToken);
                            await transaction.CommitAsync(cancellationToken);
                            res.Msg = "修改医生成功!";
                            res.Code = ApiEnum.Success;
                            res.Data = doctor.Id;
                            _logger.LogInformation($"修改医生成功，ID:{doctor.Id}");
                        }
                        else
                        {
                            await transaction.RollbackAsync(cancellationToken);
                            res.Msg = "修改医生失败!";
                            res.Code = ApiEnum.Fail;
                            res.Data = r;
                            _logger.LogError("修改医生失败");
                        }
                    }
                    catch (System.Exception ex)
                    {
                        await transaction.RollbackAsync(cancellationToken);
                        res.Msg = "修改医生异常: " + ex.Message;
                        res.Code = ApiEnum.Fail;
                        _logger.LogError($"修改医生异常:{ex.Message}");
                    }
                }
                return res;
            }
            catch (System.Exception ex)
            {
                res.Msg = "修改医生异常: " + ex.Message;
                res.Code = ApiEnum.Fail;
                _logger.LogError($"修改医生异常:{ex.Message}");
                return res;
            }
        }
    }
} 